; ** por compatibilidad se omiten tildes **
; ==============================================================================
; TRABAJO PRACTICO 3 - System Programming - ORGANIZACION DE COMPUTADOR II - FCEN
; ==============================================================================
; KERNEL

BITS 16

%include "macrosmodoreal.mac"
%include "macrosmodoprotegido.mac"

%define KORG 0x1200

global start
extern tsss
extern gdt
extern GDT_DESC
extern IDT_DESC
extern inicializar_idt

extern inicializar_mmu
extern inicializar_dir_tarea

extern deshabilitar_pic
extern resetear_pic
extern habilitar_pic

; PUNTO DE ENTRADA DEL KERNEL
start:
		cli ;pues que no me interrumpan por ahora
		jmp bienvenida

		;aca ponemos todos los mensajes
		iniciando: db 'Iniciando el kernel'
		iniciando_len equ $ - iniciando

bienvenida:
		IMPRIMIR_MODO_REAL iniciando, iniciando_len, 0x07, 0, 0

		; habilitar A20
		call deshabilitar_A20
		call checkear_A20
		call habilitar_A20
		call checkear_A20
		
		; dehsabilitar las interrupciones
		cli		
		
		; cargar la GDT
		lgdt [GDT_DESC]
		
		; setear el bit PE del registro CR0
		mov eax, cr0
		or eax, 1
		mov cr0, eax ;Activamos el bit P de protegido
		
		; pasar a modo protegido
		;Queremos que CS vaya a 0x50 (Indice A de GDT) (Codigo Nivel 0)
		jmp 0x50:mp ;Selector de segmento es el {index: A | gdt: 0 | rpl: 00}
						 
BITS 32
		mp:				
		; acomodar los segmentos (ds, es, gs, ss, fs)
		xor eax, eax
		mov ax, 1100000b	;{index: C | gdt: 0 | rpl: 00}
		mov ds, ax			;ds selector de segmento de datos de la ubicación 12
		mov es, ax
		mov gs, ax
		mov ss, ax
		
		mov ax, 1110000b	;{index: E | gdt: 0 | rpl: 00}
		mov fs, ax			;fs selector de segmento de video de la ubicación 14
		
		; seteo la pila del kernel a la dirección propuesta en el ejercicio         
		mov ebp, 0x21000
		mov esp, ebp
		
		; pintar pantalla, todos los colores, que bonito!
		mov ecx, 80*25*2 	;Cantidad de Bytes de la pantalla
		sub ecx, 2			;Sacamos el primer elemento
		mov ax, 0x7800		;{blink: 0b| fondo: 111b| brillante: 1b| caracter: 000b| caracterASCII: 0x00}
	
			;Limpia la pantalla:
		limpiarPantalla:
			mov [fs:ecx], ax 	;pintamos de gris toda la pantalla
			dec ecx		
			loop limpiarPantalla
		mov [fs:ecx], ax		;faltaba pi nta el primer elemento	
		
			;Primera fila negra
		mov ecx, 80*2			;80 columnas de 2Bytes cada una
		sub ecx, 2
		mov ax, 0x0F00			;{blink: 0b| fondo: 000b| brillante: 1b| caracter: 111b| caracterASCII: 0x00}
		primeraFila:
			mov[fs:ecx], ax
			dec ecx
			loop primeraFila
		mov [fs:ecx], ax
		
			;Ultima fila negra
		mov ecx, 80*2			;80 columnas de 2Bytes cada una
		mov ebx, 25*80*2
		sub ecx, 2
		sub ebx, 2
		mov ax, 0x0F00			;{blink: 0b| fondo: 000b| brillante: 1b| caracter: 111b| caracterASCII: 0x00}
		ultimaFila:
			mov [fs:ebx], ax
			dec ecx
			sub ebx, 2
			loop ultimaFila
		mov [fs:ebx], ax
		
	; EJ 2
		; inicializar la IDT
		call inicializar_idt
		lidt [IDT_DESC]
		
		;--EJEMPLO DIVISION POR CERO - DIVIDE ERROR para que salte interrupcion:--
		;mov ebx, 0
		;div ebx
		
	;EJ 3				
		; inicializar el directorio de paginas y la tabla de paginas haciendo Identity Mapping de 0x000000 a 0x1fffff
		call page_init
		
		; habilitar paginacion
		mov eax, 0x21000		;cargo la direccion del directorio en cr3
		mov cr3, eax

		mov eax, cr0				
		or  eax, 0x80000000		;habilito paginacion
		mov cr0, eax
		
		; imprimimos el nombre del grupo en la parte de arriba en Blanco
		jmp imprimirGrupo
			grupoTP: db 'Los Paraguas'
			longGrupoTP: equ $ - grupoTP	
		imprimirGrupo:
			IMPRIMIR_TEXTO grupoTP, longGrupoTP, 0x0F, 0, 0 
		
	;EJ 4	
		call inicializar_mmu
		
		mov ebx, cr3 	;Guardamos cr3
		
		xchg bx, bx					
		mov eax, 4
		push eax	
		call inicializar_dir_tarea
		add esp, 4
		mov cr3, eax	;Cambiamos el cr3 al recien creado
				
		; Imprimimos algo con el mapa de memoria cambiado
		jmp imprimirAlgo
			algoTP: db 'PROBANDO INICIALIZAR DIR_TAREA'
			longalgoTP: equ $ - algoTP	
		imprimirAlgo:
			IMPRIMIR_TEXTO algoTP, longalgoTP, 0xAF, 1, 0 
		
		xchg bx, bx	
		mov cr3, ebx ;Retorno al mapa de memoria original
		xchg bx, bx			
		
		;Ej 5: Remapeamos la PIC para que las interrupciones que genere no se choquen con las de la CPU
		call deshabilitar_pic
		call resetear_pic
		call habilitar_pic
		
		sti	;Habilitamos las interrupciones para poder imprimir números del teclado, el reloj y la interrupcion 0x45
		
		
		; inicializar memoria de tareas
		
		; inicializar tarea idle

		; inicializar todas las tsss

		; inicializar entradas de la gdt de tss

		; inicializar el scheduler		
		
		; configurar controlador de interrupciones

		; cargo la primer tarea null

		; aca salto a la primer tarea (Idle)

		jmp $

%include "a20.asm"
%include "paging.asm"
